<?php
/********************************************************************************************
** 	Autor		:	Andrés Darío Gutiérrez Poveda.			          																*
** 	Fecha  	:	Septiembre 13 de 2004.        				   	          													*
** 	Versión	:	0.1.0. 	                    			   	          															*
**	Empresa	:	Atila Servicios S.A. 			                      															*
**																																													*
*********************************************************************************************
**	Proposito:																																							*
**																																													*
** 		This class is meant to parse a .php archive to see the use of each variable and point *
**		out if there's any possible error. Note that this just a posibility, you have to check*
**		your code to know if it is really an error or it is meant to be that way.							*
**																																													*
*********************************************************************************************
**	Version 1.0.0  -  																																			*
** 	Cambios para la versión 1.0.0																														*
**																																													*
** 		- 																																										*
********************************************************************************************/ 

class Parser{

	/*******************************************************************************************
 	** 	ATTRIBUTES																																						**
  *******************************************************************************************/
	/** Path and name of the script to parse. */var $archivo;
	/** Array of colors. */var $colores; 
	/** Array of the variables use. */var $variables;
	
	/*******************************************************************************************
 	** 	CONSTANTS																																							**
  *******************************************************************************************/	
	var $prohibidos = " \"'+-*/[]()!;.,=<>";

	/*******************************************************************************************
 	** 	METHODS																																								**
  *******************************************************************************************/
  /*****************************************************************************
 	** 	NAME:																																		**
  **																																					**
 	** 	SET and GET for the archivo attribute.																	**
  **																																					**
  ******************************************************************************
 	** 	OBJETIVE:																															 	**
  **																																					**
  ** 	Methods to set and get the value of the attribute.											**
 	**																																					**
 	******************************************************************************
 	**	PARAMS:																																	**
 	**																																					**
 	**	- value: value to set.																									**
 	*****************************************************************************/
	function get_archivo(){
		return $this->archivo;
	}
	
	function set_archivo($value){
		$this->archivo = $value;
	}
	
	
	/*****************************************************************************
 	** 	NAME:																																		**
  **																																					**
 	** 	SET and GET for the colores attribute.																	**
  **																																					**
  ******************************************************************************
 	** 	OBJETIVE:																															 	**
  **																																					**
  ** 	Methods to set and get the value of the attribute.											**
 	**																																					**
 	******************************************************************************
 	**	PARAMS:																																	**
 	**																																					**
 	**	- top: Color for the headers of the report.															**
 	**	-	left: Color for the left panel of the table.													**
 	**	- font: Color for the font of the header of the table.									**
 	*****************************************************************************/
	function set_colores($top,$left,$font){
		$this->colores['top'] = $top;
		$this->colores['left'] = $left;
		$this->colores['font'] = $font;
		$this->colores['algo'] = '#FF9955';
	}


	/*****************************************************************************
  ** 	NAME:																																		**
  **																																					**
  ** 	parse ()																																**
  **																																					**
  ******************************************************************************
  ** 	Objective:																														 	**
  **																																					**
  ** 	This function parse the .php archive.																		**
  **																																					**
  ******************************************************************************
  ** 	PARAMS:			 																														**
  **																																					**
  *****************************************************************************/
	function parse(){
		$empiece = false;
		
		if($handler = fopen($this->archivo,"r")){
			while(($char = fgetc($handler)) !== false){
				if($char == "$")
					$empiece = true;
				
				if($empiece){
					$pos = strpos($this->prohibidos,$char);
					if($pos === false)
						$variable .= $char;
					else{
						if($variable == '$this'){
							$datos = $this->obtener_atributo($handler);
							$variable = $datos['variable'];
							$pos = $datos['pos'];
						}
						if((!empty($variable)) && ($variable != '$')){
							$operacion = $this->obtener_operacion($handler,$pos);
							$this->reportar($variable,$operacion);
						}
						$empiece = false;
						$variable = "";
					}
				}
			
			}
			fclose($handler);
		}else
			echo "No pude!";
	}
	
	
	/*****************************************************************************
  ** 	NAME:																																		**
  **																																					**
  ** 	parse ()																																**
  **																																					**
  ******************************************************************************
  ** 	Objective:																														 	**
  **																																					**
  ** 	This function parse the .php archive.																		**
  **																																					**
  ******************************************************************************
  ** 	PARAMS:			 																														**
  **																																					**
  *****************************************************************************/
	function obtener_atributo($file){
		$char = fgetc($file);
		$pos = strpos($this->prohibidos,$char);
		if($this->prohibidos[$pos] == '>'){
			$seguir = true;
			$datos['variable'] = "$";
			while(($seguir) && (($char = fgetc($file)) !== false)){
				$pos = strpos($this->prohibidos,$char);
				if($pos === false)
					$datos['variable'] = $datos['variable'].$char;
				else if($this->prohibidos[$pos] == '('){
					$seguir = false;
					$datos['variable'] = "";
				}else{
					$seguir = false;
					$datos['pos'] = $pos;
				} 
			}
		}else{
			$datos['variable'] = "";
			$datos['pos'] = $pos;
		}
		
		return $datos;
	}
	
	
	/*****************************************************************************
  ** 	NAME:																																		**
  **																																					**
  ** 	reportar ($variable,$operacion)																					**
  **																																					**
  ******************************************************************************
  ** 	Objective:																														 	**
  **																																					**
  ** 	This function keep count of the variable and operation of each.					**
  **																																					**
  ******************************************************************************
  ** 	PARAMS:			 																														**
  **																																					**
  **	-	variable: Name of the variable.																				**
  **	-	operacion: Code of the operation.																			**
  *****************************************************************************/
	function reportar($variable,$operacion){
		$this->variables[$variable]['contador'] = $this->variables[$variable]['contador'] + 1;
		$this->variables[$variable]['nombre'] = $variable;
		$this->variables[$variable][$operacion] = $this->variables[$variable][$operacion] + 1;
	}
	
	
	/*****************************************************************************
  ** 	NAME:																																		**
  **																																					**
  ** 	ver_reporte ()																													**
  **																																					**
  ******************************************************************************
  ** 	Objective:																														 	**
  **																																					**
  ** 	This function creates the HTML report to show.													**
  **																																					**
  ******************************************************************************
  ** 	PARAMS:			 																														**
  **																																					**
  *****************************************************************************/
	function ver_reporte(){
        if ($this->variables)
        {
            usort($this->variables,"asc");
        }
		
		/*$reporte  = "<style>.grid {font-family: Tahoma, Arial, Helvetica, sans-serif; font-size: 11px; color: #000000}</style>";
		$reporte .= "<table border=1 cellspacing=1 bordercolor=".$this->colores['top']." class='grid'>";
		$reporte .= "<tr align=center bgcolor=".$this->colores['top'].">";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Name</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Counter</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Compare</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Assign</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Concat</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>SubItem</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Operate</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Object</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Param</strong></font></td>";
		$reporte .= "<td><font color=".$this->colores['font']."><strong>Array</strong></font></td>";
		$reporte .= "<td bgcolor=".$this->colores['algo']."><font color=".$this->colores['font']."><strong>Type</strong></font></td>";
		$reporte .= "<td bgcolor=".$this->colores['algo']."><font color=".$this->colores['font']."><strong>Text</strong></font></td></tr>";*/
		// aquip
        $header = array('Name', 'Counter', 'Compare', 'Assign', 'Concat', 'SubItem', 'Operate', 'Object', 'Param', 'Array', 'Type', 'Text');
        $line = 0;
        if ($this->variables)
        {
            foreach($this->variables as $variable)
            {
                $error = false;
                $comportamiento = ''; 
                //$reporte .= "<tr><td bgcolor=".$this->colores['left'].">".$variable['nombre']."</td><td align=center>".$variable['contador']."</td>";
                $data[$line][] = $variable['nombre'];
                $data[$line][] = $variable['contador'];
                $contadortotal += $variable['contador'];
                
                for($i=0;$i<8;$i++)
                {
                    if($variable[$i] > 0)
                    {
                        $color = '';
                        $contadori[$i] = $contadori[$i] + $variable[$i];
                        $resultado = $variable['contador'] - $variable[$i];
                        $comportamiento = $this->obtener_comportamiento($resultado,$i);
                        
                        if($comportamiento['type'] != 'Normal')
                        {
                            //$comportamientos  = "<td align=center bgcolor=".$this->colores['algo'].">".$comportamiento['type']."</td>";
                            //$comportamientos .= "<td align=center bgcolor=".$this->colores['algo'].">".$comportamiento['text']."</td>";
                            $comportamento[$line]['type'] = $comportamiento['type'];
                            $comportamento[$line]['text'] = $comportamiento['text'];
                            $color = $this->colores['algo'];
                            $error = true;
                        }
                        else if(!$error)
                        {
                            $comportamento[$line]['type'] = $comportamiento['type'];
                            $comportamento[$line]['text'] = $comportamiento['text'];
                            //$comportamientos = "<td align=center>".$comportamiento['type']."</td><td align=center>".$comportamiento['text']."</td>";
                        }
                    }else
                        $color = $this->colores['left'];
                        
                    //$reporte .= "<td align=center bgcolor=".$color.">".$variable[$i]."</td>";
                    $data[$line][] = $variable[$i];
    
                }
                
                //$reporte .= $comportamientos;
                //$reporte .= "</tr>";
                $data[$line][] = $comportamento[$line]['type'];
                $data[$line][] = $comportamento[$line]['text'];
                $line ++;
            }
		
            $data[$line][] = 'Total';
            $data[$line][] = $contadortotal;
            /*$reporte .= "<tr>";
            $reporte .= "<td>Total</td><td align=center>".$contadortotal."</td>";*/
            for($i=0;$i<8;$i++)
            {
                //$reporte .= "<td align=center>".$contadori[$i]."</td>";
                $data[$line][] = $contadori[$i];
            }
            //$reporte .= "</tr>";
            $data[$line][] = '';
            $data[$line][] = '';
            //$reporte .= "</table>";
            $window = new GtkWindow;
            $window->set_title(_a('Report'));
            $window->set_default_size(740,480);
            $vbox = new GtkVBox;
            $window->add($vbox);
            $scroll = new GtkScrolledWindow;
            $vbox->pack_start($scroll, true, true);
            $list = new GtkCList(count($header), $header);
            $line = 0;
            $count_total = count($data);
            //$pix_alert = Gdk::pixmap_create_from_xpm($window->window, null, 'xpm/ico_alert.xpm');
            //$pix_pass  = Gdk::pixmap_create_from_xpm($window->window, null, 'xpm/ico_pass.xpm');
            $pix_ok    =  'xpm/ico_ok.xpm';
            foreach ($data as $dataline)
            {
                $row = $list->append($dataline);
                if ($line % 2 != 0)
                {
                    $list->set_background($row, new GdkColor('#EEEEEE'));
                }
                if ($line == $count_total -1)
                {
                    $list->set_background($row, new GdkColor('#9b96f7'));
                }
                if ($line < $count_total -1)
                {
                    if (($dataline[10] == 'WARNING') or ($dataline[10] == 'ERROR'))
                    {
                        $list->set_pixtext($row, 10, $dataline[10], 5, $pix_alert[0], $pix_alert[1]);
                        $list->set_pixtext($row, 11, $dataline[11], 5, $pix_alert[0], $pix_alert[1]);
                    }
                    else
                    {
                        $list->set_pixtext($row, 10, $dataline[10], 5, $pix_pass[0], $pix_pass[1]);
                        $list->set_pixtext($row, 11, $dataline[11], 5, $pix_pass[0], $pix_pass[1]);
                    }
                }
                
                $line ++;
            }
            $list->columns_autosize();
            $scroll->add($list);
            $button1 = new Button(array(&$window, 'hide'),    _a('OK'), $pix_ok, IMAGEBUTTON);
            $button1->set_relief(Gtk::RELIEF_NONE);
            $hbox = new GtkHBox;
            $hbox->pack_start(new GtkHBox, true, true);
            $hbox->pack_start($button1, false, false);
            $hbox->pack_start(new GtkHBox, true, true);
            $vbox->pack_start($hbox, false, false);
            $window->show_all();
        }
        
		//var_dump($data);
		return $reporte;
	}
	
	
	/*****************************************************************************
  ** 	NAME:																																		**
  **																																					**
  ** 	obtener_comportamiento ($resultado,$i)																	**
  **																																					**
  ******************************************************************************
  ** 	Objective:																														 	**
  **																																					**
  ** 	This function set the behavior of the variable and assign type and text.**
  **																																					**
  ******************************************************************************
  ** 	PARAMS:			 																														**
  **																																					**
  **	-	resultado: Result of each posibility.																	**
  **	-	type: Code of the operation.																					**
  *****************************************************************************/
	function obtener_comportamiento($resultado,$type){
		if($resultado < 0)
			$comportamiento = "ERROR: Internal counter.";
		else if($resultado == 0){
			switch($type){
				case 0: /** Compare Statements */
					$comportamiento['type'] = "ERROR";
					$comportamiento['text'] = _a("Used in compare statement but never assigned");
					break;
					
				case 1: /** Assign Statements */
					$comportamiento['type'] = "ERROR";
					$comportamiento['text'] = _a("Assigned value and never used");
					break;
					
				case 2: /** Concatenation Statements */
					$comportamiento['type'] = "WARNING";
					$comportamiento['text'] = _a("Used in concatenation statement but never assigned");
					break;
					
				case 3: /** SubItem */
					$comportamiento['type'] = "ERROR";
					$comportamiento['text'] = _a("Used as subitem in array but never assigned");
					break;
					
				case 4: /** Operate Statements */
					$comportamiento['type'] = "WARNING";
					$comportamiento['text'] = _a("Used in operate statement but never assigned");
					break;
					
				case 5: /** Object */
					$comportamiento['type'] = "ERROR";
					$comportamiento['text'] = _a("Used as an object but never created");
					break;
					
				case 6: /** Param */
					$comportamiento['type'] = "WARNING";
					$comportamiento['text'] = _a("Used as a param but never assigned");
					break;
					
				case 7: /** Array */
					$comportamiento['type'] = "WARNING";
					$comportamiento['text'] = _a("Used as an array but never used");
					break;
					
				case 8: /** Being assigned */
					$comportamiento['type'] = "WARNING";
					$comportamiento['text'] = _a("Its value is beign assign but never set");
					break;
					
				default:
					$comportamiento['type'] = "ERROR";
					$comportamiento['text'] = _a("Unknown error");
					break;
			}
		}else{
			$comportamiento['type'] = "Normal";
			$comportamiento['text'] = _a("Good use");
		}
			
		return $comportamiento;
	}
	
	
	/*****************************************************************************
  ** 	NAME:																																		**
  **																																					**
  ** 	obtener_operacion ($file,$pos)																					**
  **																																					**
  ******************************************************************************
  ** 	Objective:																														 	**
  **																																					**
  ** 	This function look for the operation in the .php archive of the variable**
  **																																					**
  ******************************************************************************
  ** 	PARAMS:			 																														**
  **																																					**
  **	-	file: File handler.																										**
  **	-	pos: Position of the 'prohibidos'.																		**
  *****************************************************************************/
	function obtener_operacion($file,$pos){
		switch($this->prohibidos[$pos]){
			case ' ':
				$char = fgetc($file);
				$pos = strpos($this->prohibidos,$char);
				$tipo = $this->obtener_operacion($file,$pos);
				break;
				
			case '=':
				$char = fgetc($file);
				if($char == '=')
					$tipo = 0;
				else
					$tipo = 1;
				break;
				
			case '<':
				$tipo = 0;
				break;
				
			case '>':
				$tipo = 0;
				break;
				
			case '!':
				$tipo = 0;
				break;
				
			case '.':
				$tipo = 2;
				break;
				
			case ']':
				$tipo = 3;
				break;
				
			case '+':
				$tipo = 4;
				break;
			
			case '-':
				$char = fgetc($file);
				if($char != '>')
					$tipo = 4;
				else
					$tipo = 5;
				break;
				
			case '*':
				$tipo = 4;
				break;
				
			case '/':
				$tipo = 4;
				break;
				
			case ')':
				$tipo = 6;
				break;
				
			case ',':
				$tipo = 6;
				break;
				
			case '[':
				$tipo = 7;
				break;
				
			case ';':
				$tipo = 6;
				break;
				
			default:
				break;
		}
		
		return $tipo;
	}
}
?>